#pragma once
#include "../../../Common/BeamSecPropCalculatorExport.h"
#include "ISectionElement.h"
#include "SGFem/Integration/IntegrationFormula/Gauss2D3X3P.h"
#include "SGFem/Integration/ShapeFunction/Quad9NodeShpFunc.h"

SG_NAMESPACE_OPEN
namespace FEMSolver
{
    namespace BeamElement
    {
        class BeamSecPropCalculator_DECLSPEC Quad9Element : public ISectionElement
        {
          public:
            Quad9Element ();
            virtual ~Quad9Element ();

            /// 初始化
            void Initialize () override;

            // 单元惯性矩/惯性积相关函数
            void CalculateGeomProp (const SG::Algebra::Matrixd& coord) override;

            /**
             * @brief           计算单元矩阵（翘曲方程、剪切应力函数方程的刚度矩阵相同）
             *
             * @param           coord         单元节点坐标
             * @param           inertiaMoment 截面的惯性矩数组，依次为[Iy Iz Iyz]
             * @param           mu            泊松比
             * @param[out]      Ke            刚度矩阵
             * @param[out]      F             荷载项（分为翘曲方程、剪切应力函数方程y向、z向3个荷载项）
             * @author   Liu Xing
             * @date     2025.10.17
             */
            void ComputeEleMatrix (const SG::Algebra::Matrixd&                           coord,
                                   const std::array<SG::DataStructure::Common::Real, 3>& inertiaMoment,
                                   const SG::DataStructure::Common::Real                 mu,
                                   _OUT SG::Algebra::Matrixd&                            Ke,
                                   _OUT std::vector<SG::Algebra::Matrixd>& F) const override;

            /**
             * @brief    计算剪切系数计算式中单元上的积分项值
             *
             * @param    coord          单元节点坐标
             * @param           inertiaMoment 截面的惯性矩数组，依次为[Iy Iz Iyz]
             * @param    eleNodePsi     单元节点Psi值
             * @param    eleNodePhi     单元节点Phi值
             * @return   剪切系数计算式中单元上的积分项值矩阵 维度(3, 1)
             */
            SG::Algebra::Matrixd ComputeShearCoeff (const SG::Algebra::Matrixd&               coord,
                                                    const std::array<SG::DataStructure::Common::Real, 3>& inertiaMoment,
                                                    const SG::DataStructure::Common::Real mu,
                                                    const SG::Algebra::Matrixd&           eleNodePsi,
                                                    const SG::Algebra::Matrixd&           eleNodePhi) const override;

            /**
             * @brief    计算单个单元扇形积
             *
             * @param    eleNodeCoord       单元节点坐标
             * @param    eleNodeOmega       单元节点翘曲函数值
             * @return   Matrixd(2, 1)      单元扇形积矩阵（Iyw,Iyz）
             * @author   Liu Xing
             * @date     2025.10.17
             */
            SG::Algebra::Matrixd ComputeSectorProduct (const SG::Algebra::Matrixd& eleNodeCoord,
                                                       const SG::Algebra::Matrixd& eleNodeOmega) const override;

            inline EleGeomProp GetGeomProp () const override    {return m_geomProp;}

          private:
            SG::FEMSolver::Element::Gauss2D3X3P       m_integForm;  // 单元积分格式
            SG::FEMSolver::Element::Quad9NodeShpFunc  m_shpFunc;    // 单元形函数
            static std::size_t                        s_nNode;      // 单元节点
            EleGeomProp                               m_geomProp;   // 单元几何属性
        };

    };  // end namespace BeamElement
};  // end namespace FEMSolver
SG_NAMESPACE_CLOSE